package com.fsq.xmfsubdomain;

import java.net.InetAddress;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;

import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;

public class BingReverseLookup extends Task<String> {
	private CountDownLatch countDownLatch;
	private LinkedBlockingQueue<String> queue;
	private Set<InetAddress> blacklist;
	private TreeView<String> id_treeview;
	private TableView<Row> id_tableview;
	private String domain;
	private Label id_status;
	private Set<String> ipList;
	private Set<Record> allRecordSet;
	private TreeItem<String> tiLevel2;

	public BingReverseLookup(CountDownLatch countDownLatch, LinkedBlockingQueue<String> queue,
							 Set<InetAddress> blacklist, TreeView<String> id_treeview, TableView<Row> id_tableview, String domain,
							 Label id_status, Set<String> ipList, Set<Record> allRecordSet, TreeItem<String> tiLevel2) {
		super();
		this.countDownLatch = countDownLatch;
		this.queue = queue;
		this.blacklist = blacklist;
		this.id_treeview = id_treeview;
		this.id_tableview = id_tableview;
		this.domain = domain;
		this.id_status = id_status;
		this.ipList = ipList;
		this.allRecordSet = allRecordSet;
		this.tiLevel2 = tiLevel2;
	}

	@Override
	protected String call() throws Exception {

		try {
			ObservableList<Row> items = id_tableview.getItems();
			String ip;
			while ((ip = queue.poll(3, TimeUnit.SECONDS)) != null) {
				// 必应反查
				// Mozilla/5.0 (Windows NT 6.3; WOW64; rv:46.0) Gecko/20100101
				// Firefox/46.0
				if (blacklist.contains(ip)) {
					continue;
				}
				System.out.println("bing反查c段ip:" + ip);
				String ip2 = ip;
				Platform.runLater(new Runnable() {

					@Override
					public void run() {
						id_status.setText("正在使用必应反查C段ip：" + ip2);

					}
				});

				String userAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0";
				CloseableHttpClient httpclient = HttpClients.custom().setUserAgent(userAgent).build();
				RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000)
						.setConnectionRequestTimeout(3000).setSocketTimeout(3000).setRedirectsEnabled(true).build();
				for (int i = 0; i <= 100; i += 10) {
					String url = "http://cn.bing.com/search?q=ip:" + ip
							+ "&go=%E6%90%9C%E7%B4%A2&qs=bs&FORM=PERE&first=" + i;
					HttpGet httpGet = new HttpGet(url);
					httpGet.setConfig(requestConfig);
					httpGet.addHeader("X-FORWARDED-FOR", ip);
					httpGet.addHeader("Referer", url);
					System.out.println("当前url:" + url);
					CloseableHttpResponse response = httpclient.execute(httpGet);
					HttpEntity entity = response.getEntity();
					String pagedoc = EntityUtils.toString(entity, "utf-8");
					if (pagedoc.contains("没有找到您要的结果") || pagedoc.contains("No results found for")) {
						// Thread.sleep(1000);
						System.out.println("没有找到您要的结果,查询下一个ip");
						break;
					}

					// System.out.println(pagedoc);
					Document doc = Jsoup.parse(pagedoc);
					Elements aElements = doc.getElementsByTag("cite");

					String domainname = null;
					for (Element element : aElements) {
						String str = element.text();
						String str1 = str.replace("https://", "");
						int j = str1.indexOf("/");
						domainname = j == -1 ? str1 : str1.substring(0, j);
						System.out.println(domainname);
						// 如果不是目标域名的子域名则下一个
						if (!domainname.contains(domain)) {
							System.out.println(domain + ": " + domainname);
							continue;
						}

						Record[] records = new Lookup(domainname).run();
						for (Record record : records) {
							if (allRecordSet.add(record)) {
								// 添加成功说明之前没有收录
								Row row = new Row(domain, domainname, ip, "必应C段反查", "2", "A记录");
								TreeItem<String> tiBbing = new TreeItem<String>(domainname);
								Platform.runLater(new Runnable() {

									@Override
									public void run() {
										tiLevel2.getChildren().add(tiBbing);
										items.add(row);
									}
								});
							} else {
								String d = domainname;
								Platform.runLater(new Runnable() {

									@Override
									public void run() {
										id_status.setText("收到来必应的域名为重复记录:" + d);
									}
								});
							}

						}
						// Thread.sleep(1000);
					}

				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			countDownLatch.countDown();
			System.out.println("反查线程退出。");
		}
		return null;
	}

}
